/*
 * VariableDeclAst.cpp
 *
 *  Created on: 5 Nov 2010
 *      Author: kn308
 */

#include <MAlice/Ast/VariableDeclAst.h>
#include <MAlice/Ast/IntegerLiteralAst.h>
#include <MAlice/Ast/AssignmentOperatorAst.h>
#include <MAlice/Ast/CharacterLiteralAst.h>
#include <MAlice/Ast/StringLiteralAst.h>
#include <MAlice/Ast/TypeAst.h>
#include <MAlice/Parser/location.hh>

namespace MAlice
{

VariableDeclAst::VariableDeclAst(location loc, const string& name,
		TypeAst* type, ExpressionAst* size, bool fixed) :
	ExpressionAst(loc), mName(name), mType(type), mSize(size), mFixed(fixed)
{
	MALICE_TRACE;
}

VariableDeclAst::~VariableDeclAst()
{
	MALICE_TRACE;
}

llvm::Value* VariableDeclAst::generate()
{
	MALICE_TRACE;
#	ifndef NDEBUG
	cout << "VariableDeclAst::generate()" << endl;
#	endif

	Value* value;
	Codegen* g = Codegen::get();
	Builder* builder = g->getBuilder();
	BasicBlock* bb = builder->GetInsertBlock();
	{
		Value* size = mSize->generate();

		// jump to the end of the function entry block
		builder->SetInsertPoint(&bb->getParent()->getEntryBlock());
		value = builder->CreateAlloca(mType->type(), size, Twine(mName));

		// push on the scope
		g->pushVar(mName, value, (mFixed) ? NULL : size);

		// default value
		AssignmentOperatorAst(mLocation,
				new VariableAst(mLocation, mName),
				g->getDefaultValue(mType->getName())).generate();
	}
	builder->SetInsertPoint(bb);

	return value;
}

}
